from django.shortcuts import render
from django.shortcuts import redirect
from . import models
from . import forms
import hashlib
import datetime
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.contrib.auth import authenticate, login
from django.contrib.auth.hashers import make_password
from django.http import JsonResponse

from login.models import User, EmailVerifyRecord
from login.forms import LoginForm, RegisterForm
from util.email_send import send_register_email
# Create your views here.

# 自定义的用户信息的验证，这样登录的时候可以使用邮箱与用户名登录
# 继承django中的ModelBackend类，并重写里面的authenticate方法
class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(email=username) | Q(username=username))
            if user:
                if user.check_password(raw_password=password):
                    return user
            return None
        except Exception as e:
            print(str(e))
            return None


def login_view(request):
    if request.method == "POST":
        # username = request.POST.get("username", "")  # 这里是利用html中的name进行获取
        # password = request.POST.get("password", "")
        login_form = LoginForm(request.POST)  # 使用表单读取数据
        if login_form.is_valid():  # 进行验证
            # 这里一定要指明数据名
            username = login_form.username
            password = login_form.password
            user = authenticate(username=username, password=password)
            if user:
                # login里面进行的主要操作是进行一些验证，然后设置session(这是重点)
                if user.is_active:
                    login(request, user)
                    # 重点，返回用户信息以及相应的状态码，这里要理解，这个返回到了login.html文件中
                    return JsonResponse({'status': 0, 'mesg': 'success', 'user': user})
                else:
                    return JsonResponse({'status': -1, 'mesg': 'error: user is not active'})
            else:
                return JsonResponse({'status': -1, 'mesg': 'error: password or account is not true'})
        else:
            return JsonResponse({'status': -1, 'mesg': 'error: 数据输入有问题'})
    elif request.method == "GET":
        return render(request, "login/login.html")


def register_view(request):
    if request.method == "POST":
        register_form = RegisterForm(request.POST)
        if register_form.is_valid():
            username = request.POST.get("email", "")
            if User.objects.filter(email=username):
                return JsonResponse({'status': -1, 'mesg': 'error: 用户已经存在'})
            password = request.POST.get("password", "")
            # 创建一个用户实例
            new_user = User()
            new_user.username = username
            # make_password()这个方法比较重要可以对密码进行哈希编码，将纯文本(未加密)的密码进行加密处理，源码中有解释
            new_user.password = make_password(password)
            new_user.is_active = False
            new_user.save()

            send_register_email(username, "register")
            return render(request, "login\login.html")  # 注册完成后跳转到登录页面
        else:
            return JsonResponse({'status': -1, 'mesg': 'error: 表单提交有问题'})
    elif request.method == "GET":
        register_form = RegisterForm()
        return render(request, 'login/register.html')


# 这里需要加上一个时间限制
def active_user(request, active_code):
    if request.method == "GET":
        all_record = EmailVerifyRecord.objects.filter(code=active_code)
        if all_record:
            for record in all_record:
                # 获取相应的邮箱
                email = record.email
                # 查找邮箱所对应的用户
                user = User.objects.get(email=email)
                user.is_active = True  # 用户激活
                user.save()
        else:
            return JsonResponse({"status": -1, "mesg": "连接失效"})
        return render(request, "login/login.html")  # 这里加上验证错误的处理


def logout_view(request):
    if request.method == "GET":
        logout(request)
        return


def hash_code(s, salt='login_regs'):  # 加点盐
    h = hashlib.sha256()
    s += salt
    h.update(s.encode())  # update方法只接收bytes类型
    return h.hexdigest()


def send_email(email, code):
    from django.core.mail import EmailMultiAlternatives
    subject = '注册确认邮件'
    text_content = '''感谢注册！\
                    如果你看到这条消息，说明你的邮箱服务器不提供HTML链接功能，请联系管理员！'''
    html_content = '''
                    <p>感谢注册<a href="http://{}/confirm/?code={}" target=blank>www.xxx.com</a>，\
                    这里是一个网站！</p>
                    <p>请点击站点链接完成注册确认！</p>
                    <p>此链接有效期为{}天！</p>
                    '''.format('127.0.0.1:8000', code, settings.CONFIRM_DAYS)
    msg = EmailMultiAlternatives(subject, text_content, settings.EMAIL_HOST_USER, [email])
    msg.attach_alternative(html_content, "text/html")
    msg.send()


def make_confirm_string(user):
    now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    code = hash_code(user.name, now)
    models.ConfirmString.objects.create(code=code, user=user,)
    return code


def index(request):
    return render(request, 'login/index.html')


# def login(request):
#     if request.session.get('is_login', None):
#         return redirect("/index/")
#     if request.method == "POST":
#         login_form = forms.UserForm(request.POST)
#         message = "请检查填写的内容！"
#         if login_form.is_valid():
#             username = login_form.cleaned_data['username']
#             password = login_form.cleaned_data['password']
#             try:
#                 user = models.User.objects.get(name=username)
#                 if not user.has_confirmed:
#                     message = "该用户还未通过邮件确认！"
#                     return render(request, 'login/login.html', locals())
#                 if user.password == hash_code(password):  # 哈希值和数据库内的值进行比对
#                     request.session['is_login'] = True
#                     request.session['user_id'] = user.id
#                     request.session['user_name'] = user.name
#                     return redirect('/index/')
#                 else:
#                     message = "密码不正确！"
#             except:
#                 message = "用户不存在！"
#         return render(request, 'login/login.html', locals())
#
#     login_form = forms.UserForm()
#     return render(request, 'login/login.html', locals())
#
#
# def register(request):
#     # 这里需要进行一些修改，应该是输入两次密码进行确认
#     if request.session.get('is_login', None):
#         # 登录状态不允许注册。你可以修改这条原则！
#         return redirect("/index/")
#     if request.method == "POST":
#         register_form = forms.RegisterForm(request.POST)
#         message = "请检查填写的内容！"
#         if register_form.is_valid():  # 获取数据
#             username = register_form.cleaned_data['username']
#             password1 = register_form.cleaned_data['password1']
#             password2 = register_form.cleaned_data['password2']
#             email = register_form.cleaned_data['email']
#             sex = register_form.cleaned_data['sex']
#             if password1 != password2:  # 判断两次密码是否相同
#                 message = "两次输入的密码不同！"
#                 return render(request, 'login/register.html', locals())
#             else:
#                 same_name_user = models.User.objects.filter(name=username)
#                 if same_name_user:  # 用户名唯一
#                     message = '用户已经存在，请重新选择用户名！'
#                     return render(request, 'login/register.html', locals())
#                 same_email_user = models.User.objects.filter(email=email)
#                 if same_email_user:  # 邮箱地址唯一
#                     message = '该邮箱地址已被注册，请使用别的邮箱！'
#                     return render(request, 'login/register.html', locals())
#
#                 # 当一切都OK的情况下，创建新用户
#
#                 new_user = models.User()
#                 new_user.name = username
#                 new_user.password = hash_code(password1)  # 使用加密密码
#                 new_user.email = email
#                 new_user.sex = sex
#                 new_user.has_confirmed = True
#                 new_user.save()
#
#                 # code = make_confirm_string(new_user)
#                 # message = "注册完成!"
#                 # send_email(email, code)
#                 # message = '请前往注册邮箱，进行邮件确认！'
#                 return render(request, 'login/confirm.html', locals())  # 跳转到等待邮件确认页面。
#     register_form = forms.RegisterForm()
#     return render(request, 'login/register.html', locals())


def logout(request):
    if not request.session.get('is_login', None):
        # 如果本来就未登录，也就没有登出一说
        return redirect("/index/")
    request.session.flush()
    # 或者使用下面的方法
    # del request.session['is_login']
    # del request.session['user_id']
    # del request.session['user_name']
    return redirect("/index/")


def user_confirm(request):
    code = request.GET.get('code', None)
    message = ''
    try:
        confirm = models.ConfirmString.objects.get(code=code)
    except:
        message = '无效的确认请求!'
        return render(request, 'login/confirm.html', locals())

    c_time = confirm.c_time
    now = datetime.datetime.now()
    if now > c_time + datetime.timedelta(settings.CONFIRM_DAYS):
        confirm.user.delete()
        message = '您的邮件已经过期！请重新注册!'
        return render(request, 'login/confirm.html', locals())
    else:
        confirm.user.has_confirmed = True
        confirm.user.save()
        confirm.delete()
        message = '感谢确认，请使用账户登录！'
        return render(request, 'login/confirm.html', locals())

